from fastapi import APIRouter, Depends, HTTPException, Request, Query, UploadFile, File, Form
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse, FileResponse
from typing import List, Optional
from sqlalchemy.orm import Session
from app.models.models import SysUser, SysFile
from app.schemas.schemas import FileResponse as FileResponseSchema
from app.utils.auth import get_current_active_user
from app.database.database import get_db
import os
import uuid
from pathlib import Path
import shutil

router = APIRouter()
templates = Jinja2Templates(directory="app/templates")

# 文件上传目录
UPLOAD_DIR = Path("app/static/uploads")
if not UPLOAD_DIR.exists():
    UPLOAD_DIR.mkdir(parents=True, exist_ok=True)

# 页面路由 - 返回文件管理页面
@router.get("/files", response_class=HTMLResponse)
async def get_files_page(request: Request):
    return templates.TemplateResponse("files.html", {"request": request})

# API路由 - 获取文件列表
@router.get("/api/files", response_model=dict)
async def get_files(
    db: Session = Depends(get_db),
    current_user: SysUser = Depends(get_current_active_user),
    page: int = Query(1, gt=0),
    size: int = Query(10, gt=0, le=100),
    file_name: Optional[str] = None,
    file_type: Optional[str] = None,
    uploader_name: Optional[str] = None
):
    """获取文件列表，支持分页和筛选"""
    # 构建查询
    query = db.query(SysFile)
    
    # 应用筛选条件
    if file_name:
        query = query.filter(SysFile.file_name.like(f"%{file_name}%"))
    if file_type:
        query = query.filter(SysFile.file_type == file_type)
    if uploader_name:
        query = query.filter(SysFile.uploader_name.like(f"%{uploader_name}%"))
    
    # 计算总数
    total = query.count()
    
    # 分页
    skip = (page - 1) * size
    files = query.order_by(SysFile.created_at.desc()).offset(skip).limit(size).all()
    
    # 计算总页数
    pages = (total + size - 1) // size
    
    return {
        "items": files,
        "total": total,
        "page": page,
        "pages": pages,
        "size": size
    }

# API路由 - 获取文件详情
@router.get("/api/files/{file_id}", response_model=FileResponseSchema)
async def get_file_detail(
    file_id: int,
    db: Session = Depends(get_db),
    current_user: SysUser = Depends(get_current_active_user)
):
    """获取文件详情"""
    file = db.query(SysFile).filter(SysFile.id == file_id).first()
    if not file:
        raise HTTPException(status_code=404, detail="文件不存在")
    
    return file

# API路由 - 上传文件
@router.post("/api/files", response_model=FileResponseSchema)
async def upload_file(
    file: UploadFile = File(...),
    remark: Optional[str] = Form(None),
    db: Session = Depends(get_db),
    current_user: SysUser = Depends(get_current_active_user)
):
    """上传文件"""
    # 生成唯一文件名
    file_extension = os.path.splitext(file.filename)[1]
    file_name = f"{uuid.uuid4()}{file_extension}"
    file_path = UPLOAD_DIR / file_name
    
    # 保存文件
    with open(file_path, "wb") as buffer:
        shutil.copyfileobj(file.file, buffer)
    
    # 获取文件类型和大小
    file_type = file_extension.lstrip(".")
    file_size = os.path.getsize(file_path)
    
    # 文件URL
    file_url = f"/static/uploads/{file_name}"
    
    # 保存文件信息到数据库
    db_file = SysFile(
        file_name=file.filename,
        file_url=file_url,
        file_type=file_type,
        file_size=file_size,
        uploader_id=current_user.id,
        uploader_name=current_user.name,
        remark=remark
    )
    db.add(db_file)
    db.commit()
    db.refresh(db_file)
    
    return db_file

# API路由 - 下载文件
@router.get("/api/files/{file_id}/download")
async def download_file(
    file_id: int,
    db: Session = Depends(get_db)
    # current_user: SysUser = Depends(get_current_active_user)
):
    """下载文件"""
    file = db.query(SysFile).filter(SysFile.id == file_id).first()
    if not file:
        raise HTTPException(status_code=404, detail="文件不存在")
    
    # 获取文件路径
    file_path = Path(f"app{file.file_url}")
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="文件不存在或已被删除")
    
    return FileResponse(
        path=str(file_path),
        filename=file.file_name,
        media_type="application/octet-stream"
    )

# API路由 - 删除文件
@router.delete("/api/files/{file_id}", response_model=dict)
async def delete_file(
    file_id: int,
    db: Session = Depends(get_db),
    current_user: SysUser = Depends(get_current_active_user)
):
    """删除文件"""
    # 检查是否为管理员或文件上传者
    file = db.query(SysFile).filter(SysFile.id == file_id).first()
    if not file:
        raise HTTPException(status_code=404, detail="文件不存在")
    
    if current_user.is_admin == 0 and file.uploader_id != current_user.id:
        raise HTTPException(status_code=403, detail="无权删除该文件")
    
    # 删除物理文件
    file_path = Path(f"app{file.file_url}")
    if file_path.exists():
        file_path.unlink()
    
    # 删除数据库记录
    db.delete(file)
    db.commit()
    
    return {"message": "文件删除成功"} 